home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / OpenGL / ideas / track.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  27.2 KB  |  1,120 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED 
  4.  * Permission to use, copy, modify, and distribute this software for 
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that 
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission. 
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  * 
  25.  * US Government Users Restricted Rights 
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37. #include <GL/glu.h>
  38. #include <GL/glx.h>
  39. #include <X11/keysym.h>
  40. #include <math.h>
  41. #include <sys/time.h>
  42. #include <stdio.h>
  43. #include "objects.h"
  44.  
  45. #define X 0
  46. #define Y 1
  47. #define Z 2
  48.  
  49. #ifndef TRUE
  50. #define TRUE 1
  51. #endif
  52. #ifndef FALSE
  53. #define FALSE 0
  54. #endif
  55.  
  56. #define DEG *M_PI/180.0
  57. #define RAD *180.0/M_PI
  58.  
  59. float move_speed;        /* Spline distance per second */
  60.  
  61. Display *dpy;
  62. Window window;
  63.  
  64. int multisample = 0;        /* Antialias polygons? */
  65. int doublebuffer = 1;        /* Doublebuffer? */
  66. int stereo = 0;            /* Use stereo? */
  67.  
  68.  
  69. #define SPEED_SLOW        0.2    /* Spline distances per second */
  70. #define SPEED_MEDIUM        0.4
  71. #define SPEED_FAST        0.7
  72. #define SPEED_SUPER_FAST    1.0
  73.  
  74. #define O_NOMS        7
  75. #define O_4MS        8
  76. #define O_8MS        9
  77. #define O_16MS        10
  78.  
  79. static int RGBA_SB_attributes[] = {
  80.   GLX_RGBA,
  81.   GLX_RED_SIZE, 1,
  82.   GLX_GREEN_SIZE, 1,
  83.   GLX_BLUE_SIZE, 1,
  84.   GLX_DEPTH_SIZE, 1,
  85.   None,
  86. };
  87.  
  88. static int RGBA_SB_ST_attributes[] = {
  89.   GLX_RGBA,
  90.   GLX_STEREO,
  91.   GLX_RED_SIZE, 1,
  92.   GLX_GREEN_SIZE, 1,
  93.   GLX_BLUE_SIZE, 1,
  94.   GLX_DEPTH_SIZE, 1,
  95.   None,
  96. };
  97.  
  98. static int RGBA_DB_attributes[] = {
  99.   GLX_RGBA,
  100.   GLX_RED_SIZE, 1,
  101.   GLX_GREEN_SIZE, 1,
  102.   GLX_BLUE_SIZE, 1,
  103.   GLX_DOUBLEBUFFER,
  104.   GLX_DEPTH_SIZE, 1,
  105.   None,
  106. };
  107.  
  108. static int RGBA_DB_ST_attributes[] = {
  109.   GLX_RGBA,
  110.   GLX_STEREO,
  111.   GLX_RED_SIZE, 1,
  112.   GLX_GREEN_SIZE, 1,
  113.   GLX_BLUE_SIZE, 1,
  114.   GLX_DOUBLEBUFFER,
  115.   GLX_DEPTH_SIZE, 1,
  116.   None,
  117. };
  118.  
  119. float idmat[4][4] = {
  120.     {1.0, 0.0, 0.0, 0.0},
  121.     {0.0, 1.0, 0.0, 0.0},
  122.     {0.0, 0.0, 1.0, 0.0},
  123.     {0.0, 0.0, 0.0, 1.0},
  124. };
  125.  
  126. float light1_ambient[] = { 0.0,0.0,0.0,1.0 };
  127. float light1_lcolor[] = { 1.0,1.0,1.0,1.0 };
  128. float light1_position[] = { 0.0,1.0,0.0,0.0 };
  129.  
  130. float light2_ambient[] = { 0.0,0.0,0.0,1.0 };
  131. float light2_lcolor[] = { 0.3,0.3,0.5,1.0 };
  132. float light2_position[] = { -1.0,0.0,0.0,0.0 };
  133.  
  134. float light3_ambient[] = { 0.2,0.2,0.2,1.0 };
  135. float light3_lcolor[] = { 0.2,0.2,0.2,1.0 };
  136. float light3_position[] = { 0.0,-1.0,0.0,0.0 };
  137.  
  138. float lmodel_LVW[] = { 0.0 };
  139. float lmodel_ambient[] = { 0.3,0.3,0.3,1.0 };
  140. float lmodel_TWO[] = { GL_TRUE };
  141.  
  142. float mat_logo_ambient[] = {0.1, 0.1, 0.1, 1.0};
  143. float mat_logo_diffuse[] = {0.5, 0.4, 0.7, 1.0};
  144. float mat_logo_specular[] = {1.0, 1.0, 1.0, 1.0};
  145. float mat_logo_shininess[] = {30.0};
  146.  
  147. float mat_holder_base_ambient[] = {0.0, 0.0, 0.0, 1.0};
  148. float mat_holder_base_diffuse[] = {0.6, 0.6, 0.6, 1.0};
  149. float mat_holder_base_specular[] = {0.8, 0.8, 0.8, 1.0};
  150. float mat_holder_base_shininess[] = {30.0};
  151.  
  152. float mat_holder_rings_ambient[] = { 0.0,0.0,0.0,1.0 };
  153. float mat_holder_rings_diffuse[] = { 0.9,0.8,0.0,1.0 };
  154. float mat_holder_rings_specular[] = { 1.0,1.0,1.0,1.0 };
  155. float mat_holder_rings_shininess[] = { 30.0 };
  156.  
  157. float mat_hemisphere_ambient[] = {0.0, 0.0, 0.0,1.0 };
  158. float mat_hemisphere_diffuse[] = {1.0, 0.2, 0.2,1.0 };
  159. float mat_hemisphere_specular[] = {0.5, 0.5, 0.5,1.0 };
  160. float mat_hemisphere_shininess[] = {20.0};
  161.  
  162. GLubyte stipple[32*32];
  163.  
  164. typedef float vector[3];
  165. typedef vector parameter[4];
  166.  
  167. /*
  168.  * Function definitions
  169.  */
  170. void initialize(char *title);
  171. void resize_window();
  172. void build_table();
  173. parameter *calc_spline_params(vector *ctl_pts, int n);
  174. void calc_spline(vector v, parameter *params, float current_time);
  175. void normalize(vector v);
  176. float dot(vector v1, vector v2);
  177. void draw_table();
  178. void draw_logo_shadow();
  179. void draw_hemisphere();
  180. void draw_logo();
  181. void draw_under_table();
  182. void draw_i();
  183. void draw_d();
  184. void draw_e();
  185. void draw_a();
  186. void draw_s();
  187. void draw_n();
  188. void draw_m();
  189. void draw_o();
  190. void draw_t();
  191.  
  192. init_materials() {
  193.   int x, y;
  194.  
  195.   /* Stipple pattern */
  196.   for (y = 0; y < 32; y++)
  197.     for (x = 0; x < 4; x++) 
  198.       stipple[y * 4 + x] = (y % 2) ? 0xaa : 0x55;
  199.  
  200.     glNewList(MAT_LOGO, GL_COMPILE); 
  201.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_logo_ambient); 
  202.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_logo_diffuse);
  203.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_logo_specular);
  204.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_logo_shininess);
  205.     glEndList(); 
  206.  
  207.     glNewList( MAT_HOLDER_BASE, GL_COMPILE);
  208.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_base_ambient); 
  209.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_base_diffuse);
  210.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_base_specular);
  211.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_base_shininess);
  212.     glEndList();
  213.  
  214.     glNewList(MAT_HOLDER_RINGS, GL_COMPILE); 
  215.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_rings_ambient); 
  216.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_rings_diffuse);
  217.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_rings_specular);
  218.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_rings_shininess);
  219.     glEndList();
  220.  
  221.     glNewList(MAT_HEMISPHERE, GL_COMPILE); 
  222.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_hemisphere_ambient); 
  223.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_hemisphere_diffuse);
  224.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_hemisphere_specular);
  225.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_hemisphere_shininess);
  226.     glEndList();
  227.  
  228. }
  229.  
  230. void init_lights() {
  231.   static float ambient[] = { 0.1, 0.1, 0.1, 1.0 };
  232.   static float diffuse[] = { 0.5, 1.0, 1.0, 1.0 };
  233.   static float position[] = { 90.0, 90.0, 150.0, 0.0 };
  234.   
  235.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  236.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  237.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  238.  
  239.   glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient);
  240.   glLightfv (GL_LIGHT1, GL_SPECULAR, light1_lcolor);
  241.   glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_lcolor);
  242.   glLightfv (GL_LIGHT1, GL_POSITION, light1_position);
  243.     
  244.   glLightfv (GL_LIGHT2, GL_AMBIENT, light2_ambient);
  245.   glLightfv (GL_LIGHT2, GL_SPECULAR, light2_lcolor);
  246.   glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_lcolor);
  247.   glLightfv (GL_LIGHT2, GL_POSITION, light2_position);
  248.  
  249.   glLightfv (GL_LIGHT3, GL_AMBIENT, light3_ambient);
  250.   glLightfv (GL_LIGHT3, GL_SPECULAR, light3_lcolor);
  251.   glLightfv (GL_LIGHT3, GL_DIFFUSE, light3_lcolor);
  252.   glLightfv (GL_LIGHT3, GL_POSITION, light3_position);
  253.   
  254.   glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_LVW);
  255.   glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  256. }
  257.  
  258. short dev, val;
  259.  
  260. float current_time=0.0;
  261. float hold_time=0.0;        /* Used when auto-running */
  262.  
  263. float tmplight[] = {
  264.     GL_POSITION, 0.0, 0.0, 0.0, 0.0, 
  265. };
  266.  
  267. GLfloat tv[4][4] = {
  268.   {1.0, 0.0, 0.0, 0.0},
  269.   {0.0, 1.0, 0.0, -1.0},
  270.   {0.0, 0.0, 1.0, 0.0},
  271.   {0.0, 0.0, 0.0, 0.0},
  272. };
  273.  
  274. #define TABLERES 12
  275.  
  276. float pcr, pcg, pcb, pca;
  277.  
  278. vector table_points[TABLERES+1][TABLERES+1];
  279. int tablecolors[TABLERES+1][TABLERES+1];
  280.  
  281. vector paper_points[4] = {
  282.     {-0.8, 0.0, 0.4},
  283.     {-0.2, 0.0, -1.4},
  284.     {1.0, 0.0, -1.0},
  285.     {0.4, 0.0, 0.8},
  286. };
  287.  
  288. float dot(vector, vector);
  289.  
  290. #define TIME 15
  291. #define START_TIME 0.6
  292.  
  293. vector light_pos_ctl[] = {
  294.  
  295.     {0.0, 1.8, 0.0},
  296.     {0.0, 1.8, 0.0},
  297.     {0.0, 1.6, 0.0},
  298.  
  299.     {0.0, 1.6, 0.0},
  300.     {0.0, 1.6, 0.0},
  301.     {0.0, 1.6, 0.0},
  302.     {0.0, 1.4, 0.0},
  303.  
  304.     {0.0, 1.3, 0.0},
  305.     {-0.2, 1.5, 2.0},
  306.     {0.8, 1.5, -0.4},
  307.     {-0.8, 1.5, -0.4},
  308.  
  309.     {0.8, 2.0, 1.0},
  310.     {1.8, 5.0, -1.8},
  311.     {8.0, 10.0, -4.0},
  312.     {8.0, 10.0, -4.0},
  313.     {8.0, 10.0, -4.0},
  314. };
  315.  
  316. vector logo_pos_ctl[] = {
  317.  
  318.     {0.0, -0.5, 0.0},
  319.  
  320.     {0.0, -0.5, 0.0},
  321.     {0.0, -0.5, 0.0},
  322.  
  323.     {0.0, -0.5, 0.0},
  324.     {0.0, -0.5, 0.0},
  325.     {0.0, -0.5, 0.0},
  326.     {0.0, 0.0, 0.0},
  327.  
  328.     {0.0, 0.6, 0.0},
  329.     {0.0, 0.75, 0.0},
  330.     {0.0, 0.8, 0.0},
  331.     {0.0, 0.8, 0.0},
  332.  
  333.     {0.0, 0.5, 0.0},
  334.     {0.0, 0.5, 0.0},
  335.     {0.0, 0.5, 0.0},
  336.     {0.0, 0.5, 0.0},
  337.     {0.0, 0.5, 0.0},
  338. };
  339.  
  340.  
  341. vector logo_rot_ctl[] = {
  342.  
  343.     {0.0, 0.0, -18.4},
  344.  
  345.     {0.0, 0.0, -18.4},
  346.     {0.0, 0.0, -18.4},
  347.  
  348.     {0.0, 0.0, -18.4},
  349.     {0.0, 0.0, -18.4},
  350.     {0.0, 0.0, -18.4},
  351.     {0.0, 0.0, -18.4},
  352.     {0.0, 0.0, -18.4},
  353.  
  354. /*    {90.0, 0.0, -90.0},
  355.     {180.0, 180.0, 90.0}, */
  356.     {240.0, 360.0, 180.0},
  357.     {90.0, 180.0, 90.0},
  358.  
  359.     {11.9, 0.0, -18.4},
  360.     {11.9, 0.0, -18.4},
  361.     {11.9, 0.0, -18.4},
  362.     {11.9, 0.0, -18.4},
  363.     {11.9, 0.0, -18.4},
  364. };
  365.  
  366.  
  367. vector view_from_ctl[] = {
  368.  
  369.     {-1.0, 1.0, -4.0},
  370.  
  371.     {-1.0, -3.0, -4.0},    /* 0 */
  372.     {-3.0, 1.0, -3.0},    /* 1 */
  373.  
  374.     {-1.8, 2.0, 5.4},    /* 2 */
  375.     {-0.4, 2.0, 1.2},    /* 3 */
  376.     {-0.2, 1.5, 0.6},    /* 4 */
  377.     {-0.2, 1.2, 0.6},    /* 5 */
  378.  
  379.     {-0.8, 1.0, 2.4},    /* 6 */
  380.     {-1.0, 2.0, 3.0},    /* 7 */
  381.     {0.0, 4.0, 3.6},    /* 8 */
  382.     {-0.8, 4.0, 1.2},    /* 9 */
  383.  
  384.     {-0.2, 3.0, 0.6},    /* 10 */
  385.     {-0.1, 2.0, 0.3},    /* 11 */
  386.     {-0.1, 2.0, 0.3},    /* 12 */
  387.     {-0.1, 2.0, 0.3},    /* 13 */
  388.     {-0.1, 2.0, 0.3},    /* 13 */
  389.  
  390.  
  391. };
  392.  
  393. vector view_to_ctl[] = {
  394.  
  395.     {-1.0, 1.0, 0.0},
  396.  
  397.     {-1.0, -3.0, 0.0},
  398.     {-1.0, 1.0, 0.0},
  399.  
  400.     {0.1, 0.0, -0.3},
  401.     {0.1, 0.0, -0.3},
  402.     {0.1, 0.0, -0.3},
  403.     {0.0, 0.2, 0.0},
  404.  
  405.     {0.0, 0.6, 0.0},
  406.     {0.0, 0.8, 0.0},
  407.     {0.0, 0.8, 0.0},
  408.     {0.0, 0.8, 0.0},
  409.  
  410.     {0.0, 0.8, 0.0},
  411.     {0.0, 0.8, 0.0},
  412.     {0.0, 0.8, 0.0},
  413.     {0.0, 0.8, 0.0},
  414.     {0.0, 0.8, 0.0},
  415.  
  416. };
  417.  
  418.  
  419. vector view_from, view_to, light_pos, logo_pos, logo_rot;
  420.  
  421. parameter *view_from_spline, *view_to_spline,
  422.       *light_pos_spline, *logo_pos_spline,
  423.       *logo_rot_spline;
  424.  
  425. parameter *calc_spline_params(vector *, int);
  426.  
  427. double a3, a4;
  428.  
  429. void ideas_usage(void)
  430. {
  431.   fprintf(stderr, "Usage: ideas [-a] [-m] [-d] -s{1-4}\n");
  432.   fprintf(stderr, "Press ESC to quit, 1-4 to control speed, any other key\n");
  433.   fprintf(stderr, "to pause.\n");
  434. }
  435.  
  436. void main(int argc, char **argv)
  437. {
  438.   float x, y, z, c;
  439.   int pick;
  440.   int i;
  441.   int auto_run;        /* If set, then automatically run forever */
  442.   struct timeval start;
  443.   struct timeval current;
  444.   float timediff;    
  445.   float timeoffset;    /* Used to compute timing */
  446.   float new_speed;    /* Set new animation speed? */
  447.   int resetclock;    /* Reset the clock? */
  448.   int timejerk;        /* Set to indicate time jerked! (menu pulled down) */
  449.   int paused = 0;    /* Paused? */
  450.   int right = 0;    /* Draw right eye? */
  451.  
  452.   XEvent event;
  453.   char buffer[5];
  454.   int bufsize = 5;
  455.   KeySym key;
  456.   XComposeStatus compose;
  457.   
  458.   /* .4 spline distance per second by default */
  459.   move_speed = SPEED_MEDIUM;
  460.   new_speed = SPEED_MEDIUM;
  461.   timeoffset = START_TIME;
  462.   
  463.   auto_run = 0;    /* Don't automatically run forever */
  464.   for (i = 1; i < argc; i++) {
  465.     if (argv[i][0] != '-') {
  466.       break;
  467.     }
  468.     
  469.     switch(argv[i][1]) {
  470.     case 'a':    /* Keep running forever */
  471.       auto_run = 1;
  472.       break;
  473.     case 'm':    /* Multisample */
  474.       multisample = 1;
  475.       break;
  476.     case 'd':    /* Single buffer */
  477.       doublebuffer = 0;
  478.       break;
  479.     case 'S':    /* Stereo mode */
  480.       stereo = 1;
  481.       break;
  482.     case 's':
  483.       switch(argv[i][2]) {
  484.       case '1':
  485.     move_speed = new_speed = SPEED_SLOW;
  486.     break;
  487.       case '2':
  488.     move_speed = new_speed = SPEED_MEDIUM;
  489.     break;
  490.       case '3':
  491.     move_speed = new_speed = SPEED_FAST;
  492.     break;
  493.       case '4':
  494.     move_speed = new_speed = SPEED_SUPER_FAST;
  495.     break;
  496.       }
  497.       break;
  498.     default:
  499.       ideas_usage();
  500.       break;
  501.     }
  502.   }
  503.   
  504.   initialize(argv[0]);
  505.   
  506.   current_time = timeoffset;
  507.   resetclock = 1;
  508.   timejerk = 0;
  509.   while (TRUE) {
  510.     if ((current_time) > (TIME*1.0)-3.0) {
  511.       if (auto_run) {
  512.     hold_time += current_time - (TIME - 3.001);
  513.     if (hold_time > 3.0) {    /* 3 second hold */
  514.       hold_time = 0.0;
  515.       resetclock = 1;
  516.     }
  517.       }
  518.       current_time = TIME*1.0-3.001;
  519.     }
  520.     while(XPending(dpy)) {
  521.       XNextEvent(dpy, &event);
  522.       switch(event.type) {
  523.       case ConfigureNotify:
  524.     resize_window();
  525.     break;
  526.       case ButtonPress:
  527.     if (event.xbutton.button == 1) {
  528.       resetclock = 1;
  529.       paused = 0;
  530.     }
  531.     break;
  532.       case KeyPress:
  533.     XLookupString(&event.xkey, buffer, bufsize, &key, &compose);
  534.     if (key == XK_Escape) exit(0);
  535.     else if (key == XK_1 || key == XK_KP_1) 
  536.       new_speed = SPEED_SLOW;
  537.     else if (key == XK_2 || key == XK_KP_2) 
  538.       new_speed = SPEED_MEDIUM;
  539.     else if (key == XK_3 || key == XK_KP_3) 
  540.       new_speed = SPEED_FAST;
  541.     else if (key == XK_4 || key == XK_KP_4) 
  542.       new_speed = SPEED_SUPER_FAST;
  543.     else {
  544.       if (paused) timejerk = 1;
  545.       paused = ~paused;
  546.     }
  547.     break;
  548.       }
  549.     }
  550.  
  551.     if (stereo) {
  552.       right = ~right;
  553.       if (right) glDrawBuffer((doublebuffer) ? GL_BACK_RIGHT : GL_RIGHT);
  554.       else glDrawBuffer((doublebuffer) ? GL_BACK_LEFT : GL_LEFT);
  555.     }
  556.  
  557.     calc_spline(view_from, view_from_spline, current_time);
  558.     calc_spline(view_to, view_to_spline, current_time);
  559.     calc_spline(light_pos, light_pos_spline, current_time);
  560.     calc_spline(logo_pos, logo_pos_spline, current_time);
  561.     calc_spline(logo_rot, logo_rot_spline, current_time);
  562.     
  563.     tmplight[1] = light_pos[X] - logo_pos[X];
  564.     tmplight[2] = light_pos[Y] - logo_pos[Y];
  565.     tmplight[3] = light_pos[Z] - logo_pos[Z];
  566.     
  567.     glNewList(LIGHT_TMP, GL_COMPILE); 
  568.     glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, * tmplight); 
  569.     glEndList();
  570.     
  571.     tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y];
  572.     
  573.     glColor3ub(0,  0,  0);
  574.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
  575.     
  576.     /*
  577.      * SHADOW
  578.      */
  579.     glMatrixMode(GL_MODELVIEW);
  580.     glLoadIdentity();
  581.     gluLookAt(view_from[X], view_from[Y], view_from[Z], 
  582.           view_to[X], view_to[Y], view_to[Z],
  583.           0.0, 1.0, 0.0);
  584.     
  585.     if (view_from[Y] > 0.0) draw_table();
  586.  
  587.     glEnable(GL_CULL_FACE); 
  588.     glDisable(GL_DEPTH_TEST); 
  589.  
  590.     if (logo_pos[Y] < 0.0) {
  591.       
  592.       if (logo_pos[Y]>-0.33) {
  593.     /* We're emerging from the table */
  594.     c = 1.0 - (logo_pos[Y]) / -0.33;
  595.     pca /= 4.0;
  596.     glColor3ub((int)(128.0*(1.0-c)*0.5 + 255.0*pca*c),
  597.            (int)(102.0*(1.0-c)*0.5 + 255.0*pca*c),
  598.            (int)(179.0*(1.0-c)*0.5 + 200.0*pca*c));
  599.       } else {
  600.     /* Still under table */
  601.     glColor3ub(128/2,  102/2,  179/2);
  602.       }
  603.       
  604.       glPushMatrix();
  605.       glScalef(0.04,  0.0,  0.04);
  606.       glRotatef(0.1 * (-900), 1.0, 0.0, 0.0);
  607.       glRotatef(0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  608.       glRotatef(0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  609.       glRotatef(0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  610.       glRotatef(0.1 * (353), 1.0, 0.0, 0.0);
  611.       glRotatef(0.1 * (450), 0.0, 1.0, 0.0);
  612.       draw_logo_shadow();
  613.       glPopMatrix();
  614.     }
  615.     
  616.     if (logo_pos[Y] > 0.0) {
  617.       glPushMatrix();
  618.       if (logo_pos[Y]<0.33) {
  619.     pca /= 4.0;
  620.     c = 1.0 - (logo_pos[Y])/0.33;
  621.     glColor3ub((int)(255.0*pca*c),
  622.            (int)(255.0*pca*c),
  623.            (int)(200.0*pca*c));
  624.       } else {
  625.     glColor3ub(0, 0, 0);
  626.       }
  627.       
  628.       glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  629.       glMultMatrixf(&tv[0][0]);
  630.       glTranslatef(-light_pos[X]+logo_pos[X],
  631.            -light_pos[Y]+logo_pos[Y],
  632.            -light_pos[Z]+logo_pos[Z]);
  633.       glScalef(0.04,  0.04,  0.04);
  634.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  635.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  636.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  637.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  638.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  639.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  640.  
  641.  
  642.       glEnable(GL_POLYGON_STIPPLE);
  643.       glPolygonStipple(stipple);
  644.       draw_logo_shadow();
  645.       glDisable(GL_POLYGON_STIPPLE);
  646.       glPopMatrix();
  647.     }
  648.     /*
  649.      * DONE SHADOW 
  650.      */
  651.  
  652.  
  653.     glEnable(GL_DEPTH_TEST);
  654.     glDisable(GL_CULL_FACE);
  655.     glEnable(GL_LIGHTING);
  656.  
  657.     glMatrixMode(GL_PROJECTION);
  658.     glLoadIdentity();
  659.     gluPerspective(.1*(450),  5.0/4.0,  0.5,  20.0);
  660.     glMatrixMode(GL_MODELVIEW);
  661.     glLoadMatrixf(&idmat[0][0]); 
  662.     
  663.     gluLookAt(view_from[X],  view_from[Y],  view_from[Z],
  664.           view_to[X],  view_to[Y],  view_to[Z], 
  665.           0.0, 1.0, 0.0);
  666.     
  667.     glCallList( MAT_HOLDER_RINGS); 
  668. /*    glEnable(GL_FRONT); */
  669.     
  670.     glPushMatrix();
  671.     glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  672.     glScalef(0.1,  0.1,  0.1);
  673.     
  674.     x = light_pos[X] - logo_pos[X];
  675.     y = light_pos[Y] - logo_pos[Y];
  676.     z = light_pos[Z] - logo_pos[Z];
  677.     
  678.     if (x!=0.0) {
  679.       a3 = -atan2(z, x)*10.0 RAD;
  680.     } else a3 = 0.0;
  681.     
  682.     a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD;
  683.     
  684.     glRotatef (0.1 * ((int)a3), 0.0, 1.0, 0.0);
  685.     glRotatef (0.1 * ((int)a4), 0.0, 0.0, 1.0);
  686.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  687.     
  688.     glEnable(GL_LIGHT2);
  689.     glEnable(GL_LIGHT3);
  690.     glCallList(MAT_HEMISPHERE);
  691.     glEnable(GL_NORMALIZE);
  692.     draw_hemisphere();
  693.     glDisable(GL_NORMALIZE);
  694.     glPopMatrix();
  695.  
  696.     glDisable(GL_LIGHT2);
  697.     glDisable(GL_LIGHT3); 
  698.     glEnable(GL_LIGHT1);
  699.     glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
  700.     
  701.     if (logo_pos[Y] > -0.33) {
  702.  
  703.       glCallList(MAT_LOGO);
  704.     
  705.       glPushMatrix();
  706.       glTranslatef(logo_pos[X],  logo_pos[Y],  logo_pos[Z]);
  707.       glScalef(0.04,  0.04,  0.04);
  708.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  709.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  710.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  711.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  712.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  713.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  714.       glEnable(GL_LIGHTING);
  715.       draw_logo();
  716.       glPopMatrix();
  717.     }
  718.     
  719.     if (view_from[Y] < 0.0) draw_under_table();
  720.     
  721.     glXSwapBuffers(dpy, window);
  722.     
  723.     /* Time jerked -- adjust clock appropriately */
  724.     if (timejerk) {
  725.       timejerk = 0;
  726.       timeoffset = current_time;
  727.       gettimeofday(&start, NULL);
  728.     }
  729.     
  730.     /* Reset our timer */
  731.     if (resetclock) {
  732.       resetclock = 0;
  733.       paused = 0;
  734.       timeoffset = START_TIME;
  735.       gettimeofday(&start, NULL);
  736.     }
  737.     
  738.     /* Compute new time */
  739.     gettimeofday(¤t, NULL);
  740.     timediff = (current.tv_sec - start.tv_sec) + 
  741.       (current.tv_usec - start.tv_usec) / 1000000.0;
  742.     if (!paused) current_time = timediff * move_speed + timeoffset;
  743.     
  744.     /* Adjust to new speed */
  745.     if (new_speed != move_speed) {
  746.       move_speed = new_speed;
  747.       timeoffset = current_time;
  748.       gettimeofday(&start, NULL);
  749.     }
  750.   }
  751. }
  752.  
  753. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  754. {
  755.   if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  756.     return GL_TRUE;
  757.   }
  758.   return GL_FALSE;
  759. }
  760.  
  761. void resize_window() 
  762. {
  763.   XWindowAttributes windowattr;
  764.   
  765.   XGetWindowAttributes(dpy, window, &windowattr);
  766.   glMatrixMode(GL_PROJECTION);
  767.   glLoadIdentity();
  768.   gluPerspective (45.0, 5.0/4.0, 0.5, 20.0); 
  769.   glMatrixMode(GL_MODELVIEW);
  770.   glLoadIdentity();
  771.   glViewport(0, 0, windowattr.width, windowattr.height);
  772. }
  773.  
  774. void initialize(char *title)
  775. {
  776.     char *t, *strrchr();
  777.     int multiAvail;
  778.     int can_ogl, can_zbuffer, can_rgba;
  779.  
  780.     XVisualInfo *vi;
  781.     XSetWindowAttributes swa;
  782.     XSizeHints hints;
  783.     XEvent ev;
  784.     GLXContext cx;
  785.     int *attr;
  786.  
  787.     dpy = XOpenDisplay(0);
  788.     if (dpy == NULL) {
  789.       fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  790.       exit(1);
  791.     }
  792.  
  793.     attr = doublebuffer ? 
  794.       (stereo ? RGBA_DB_ST_attributes : RGBA_DB_attributes) :
  795.     (stereo ? RGBA_SB_ST_attributes : RGBA_SB_attributes);
  796.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), attr);
  797.     if (vi == NULL && stereo) {
  798.       fprintf(stderr, "Unable to find stereo visual.\n");
  799.       stereo = 0;
  800.       attr = doublebuffer ? RGBA_DB_attributes : RGBA_SB_attributes;
  801.       vi = glXChooseVisual(dpy, DefaultScreen(dpy), attr);
  802.     }
  803.     if (vi == NULL) {
  804.       fprintf(stderr, "No matching visual on \"%s\"\n",
  805.           getenv("DISPLAY"));
  806.       exit(1);
  807.     }
  808.     
  809.     glXGetConfig(dpy, vi, GLX_USE_GL, &can_ogl);
  810.     if (!can_ogl) {
  811.       system("inform 'Your system must support OpenGL to run ideas'");
  812.       exit(1);
  813.     }
  814.     glXGetConfig(dpy, vi, GLX_RGBA, &can_rgba);
  815.     if (!can_rgba) {
  816.       system("inform 'Your system must support RGB mode to run ideas'");
  817.       exit(1);
  818.     }
  819.     glXGetConfig(dpy, vi, GLX_DEPTH_SIZE, &can_zbuffer);
  820.     if (can_zbuffer == 0) {
  821.     system("inform 'Your system must have a z-buffer to run ideas'");
  822.     exit(1);
  823.     }
  824.     swa.border_pixel = 0;
  825.     swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
  826.                            vi->visual, AllocNone);
  827.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
  828.       ButtonPressMask;
  829.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10, 50, 50,
  830.                0, vi->depth, InputOutput, vi->visual,
  831.                CWBorderPixel | CWColormap | CWEventMask, &swa);
  832.     XStoreName(dpy, window, "Ideas");
  833.     
  834.     hints.width = 500;
  835.     hints.height = 400;
  836.     hints.min_aspect.x = 5;
  837.     hints.min_aspect.y = 4;
  838.     hints.max_aspect.x = 5;
  839.     hints.max_aspect.y = 4;
  840.     hints.flags = PSize | PAspect;
  841.     XSetNormalHints(dpy, window, &hints);
  842.  
  843.     XMapWindow(dpy, window);
  844.     XIfEvent(dpy, &ev, WaitForMapNotify, (char *)window);
  845.     
  846.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  847.     if (!glXMakeCurrent(dpy, window, cx)) {
  848.       fprintf(stderr, "Can't make window current to context\n");
  849.       exit(1);
  850.     }
  851.  
  852.     if (multisample) glEnable(GL_POLYGON_SMOOTH); 
  853.     
  854.     init_lights();
  855.     init_materials();
  856.  
  857.     build_table();
  858.  
  859.     view_from_spline = calc_spline_params(view_from_ctl, TIME);
  860.     view_to_spline = calc_spline_params(view_to_ctl, TIME);
  861.     light_pos_spline = calc_spline_params(light_pos_ctl, TIME);
  862.     logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME);
  863.     logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME);
  864.  
  865.     resize_window();
  866.  
  867.     glMatrixMode(GL_MODELVIEW);
  868. }
  869.  
  870.  
  871. void build_table() 
  872. {
  873.     float i, j;
  874.  
  875.     for (j=0.0; j<=TABLERES*1.0; j+=1.0) {
  876.     for (i=0.0; i<=TABLERES*1.0; i+=1.0) {
  877.         table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0;
  878.         table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0;
  879.         table_points[(int)j][(int)i][Y] = 0.0;
  880.     }
  881.     }
  882. }
  883.  
  884.  
  885. void draw_table()
  886. {
  887.  
  888.     float x, z, c;
  889.     int i, j;
  890.     int k, l;
  891.     float m, n;
  892.     float ov[3], lv[3];
  893.  
  894.     glDisable(GL_DEPTH_TEST);
  895.     glDisable(GL_LIGHTING);
  896.  
  897.     ov[X] = light_pos[X]-logo_pos[X];
  898.     ov[Y] = light_pos[Y]-logo_pos[Y];
  899.     ov[Z] = light_pos[Z]-logo_pos[Z];
  900.  
  901.     normalize(ov);
  902.  
  903.     for (j=0; j<=TABLERES; j++) {
  904.       for (i=0; i<=TABLERES; i++) {
  905.     lv[X] = light_pos[X] - table_points[j][i][X];
  906.     lv[Y] = light_pos[Y] - table_points[j][i][Y];
  907.     lv[Z] = light_pos[Z] - table_points[j][i][Z];
  908.     normalize(lv);
  909.     if ((c = dot(lv, ov))<0.0) c = 0.0;
  910.     c = c * c * c * lv[Y] * 255.0;
  911.     /* fade */
  912.     if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  913.       c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  914.     
  915.     tablecolors[j][i] = (int)c;
  916.       }
  917.     }
  918.     
  919.     
  920.     for (l=0; l<TABLERES; l++) {
  921.       
  922.       glBegin(GL_TRIANGLE_STRIP);
  923.       for (k=0; k<=TABLERES; k++) {
  924.     glColor3ub(tablecolors[l][k],
  925.            tablecolors[l][k],
  926.            tablecolors[l][k]);
  927.     glVertex3fv(table_points[l][k]);
  928.  
  929.     glColor3ub(tablecolors[l+1][k],
  930.            tablecolors[l+1][k], 
  931.            tablecolors[l+1][k]);
  932.     glVertex3fv(table_points[l+1][k]);
  933.     
  934.       }
  935.     glEnd();
  936.     }
  937.  
  938.     if (logo_pos[Y]>-0.33 && logo_pos[Y]<0.33) {
  939.     glEnable(GL_DEPTH_TEST);
  940.     }
  941.  
  942.     pca = 0.0;
  943.     glBegin(GL_POLYGON);
  944.     for (i=0; i<4; i++) {
  945.       lv[X] = light_pos[X] - paper_points[i][X];
  946.       lv[Y] = light_pos[Y] - paper_points[i][Y];
  947.       lv[Z] = light_pos[Z] - paper_points[i][Z];
  948.       normalize(lv);
  949.       if ((c = dot(lv, ov))<0.0) c = 0.0;
  950.       c = c * c * c * lv[Y];
  951.       /* fade */
  952.       if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  953.     c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  954.       
  955.       pcr = c * 255; pcg = c * 255; pcb = c * 200;
  956.       pca += c;
  957.       glColor3ub((int)pcr,  (int)pcg,  (int)pcb);
  958.       glVertex3fv(paper_points[i]);
  959.     }
  960.     glEnd();
  961.  
  962.     glPushMatrix();
  963.     glRotatef (0.1 * (-184), 0.0, 1.0, 0.0);
  964.     glTranslatef(-0.3, 0.0, -0.8);
  965.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  966.     glScalef(0.015, 0.015, 0.015);
  967.  
  968.  
  969.     if (current_time>TIME*1.0-5.0) {
  970.     c = (current_time-(TIME*1.0-5.0))/2.0;
  971.     glColor3ub((int)(c*255.0),  (int)(c*255.0),  (int)(c*255.0));
  972.     } else glColor3ub(0,  0,  0);
  973.  
  974.     glDisable(GL_DEPTH_TEST);
  975.  
  976.     draw_i();
  977.     glTranslatef(3.0,  0.0,  0.0);
  978.  
  979.     draw_d();
  980.     glTranslatef(6.0,  0.0,  0.0);
  981.  
  982.     draw_e();
  983.     glTranslatef(5.0,  0.0,  0.0);
  984.  
  985.     draw_a();
  986.     glTranslatef(6.0,  0.0,  0.0);
  987.  
  988.     draw_s();
  989.     glTranslatef(10.0,  0.0,  0.0);
  990.  
  991.     draw_i();
  992.     glTranslatef(3.0,  0.0,  0.0);
  993.  
  994.     draw_n();
  995.     glTranslatef(-31.0,  -13.0,  0.0);
  996.  
  997.     draw_m();
  998.     glTranslatef(10.0,  0.0,  0.0);
  999.  
  1000.     draw_o();
  1001.     glTranslatef(5.0,  0.0,  0.0);
  1002.  
  1003.     draw_t();
  1004.     glTranslatef(4.0,  0.0,  0.0);
  1005.  
  1006.     draw_i();
  1007.     glTranslatef(3.5,  0.0,  0.0);
  1008.  
  1009.     draw_o();
  1010.     glTranslatef(5.0,  0.0,  0.0);
  1011.  
  1012.     draw_n();
  1013.  
  1014.     glPopMatrix();
  1015.  
  1016. }
  1017.  
  1018.  
  1019.  
  1020. void draw_under_table() 
  1021. {
  1022.     int k, l;
  1023.  
  1024.     if(FALSE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  1025.  
  1026.  
  1027.     glColor3ub(0,  0,  0);
  1028.  
  1029.     for (l=0; l<TABLERES; l++) {
  1030.  
  1031.     glBegin(GL_TRIANGLE_STRIP);
  1032.     for (k=0; k<=TABLERES; k++) {
  1033.  
  1034.         glVertex3fv(table_points[l][k]);
  1035.         glVertex3fv(table_points[l+1][k]);
  1036.  
  1037.     }
  1038.     glEnd();
  1039.     }
  1040.  
  1041.     if(TRUE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  1042.  
  1043. }
  1044.  
  1045.  
  1046.  
  1047. void calc_spline(vector v, parameter *params, float current_time)
  1048. {
  1049.  
  1050.     float t, tt;
  1051.     int i, j;
  1052.  
  1053.     tt = t = current_time - (float)((int)current_time);
  1054.  
  1055.     for (i=0; i<3; i++) {
  1056.  
  1057.  
  1058.     v[i] = params[(int)current_time][3][i] +
  1059.            params[(int)current_time][2][i] * t +
  1060.            params[(int)current_time][1][i] * t * t +
  1061.            params[(int)current_time][0][i] * t * t * t;
  1062.     }
  1063.  
  1064. }
  1065.  
  1066.  
  1067. parameter *calc_spline_params(vector *ctl_pts, int n)
  1068. {
  1069.  
  1070.     int i, j;
  1071.     parameter *params;
  1072.  
  1073.     if (n<4) {
  1074.     fprintf(stderr,
  1075.         "calc_spline_params: not enough control points\n");
  1076.     return (NULL);
  1077.     }
  1078.  
  1079.     params = (parameter *)malloc(sizeof(parameter) * (n-3));
  1080.  
  1081.     for (i=0; i<n-3; i++) {
  1082.  
  1083.     for (j=0; j<3; j++) {
  1084.  
  1085.         params[i][3][j] = ctl_pts[i+1][j];
  1086.         params[i][2][j] = ctl_pts[i+2][j] - ctl_pts[i][j];
  1087.         params[i][1][j] =  2.0 * ctl_pts[i][j] +
  1088.                   -2.0 * ctl_pts[i+1][j] +
  1089.                    1.0 * ctl_pts[i+2][j] +
  1090.                   -1.0 * ctl_pts[i+3][j];
  1091.         params[i][0][j] = -1.0 * ctl_pts[i][j] +
  1092.                    1.0 * ctl_pts[i+1][j] +
  1093.                   -1.0 * ctl_pts[i+2][j] +
  1094.                    1.0 * ctl_pts[i+3][j];
  1095.  
  1096.     }
  1097.     }
  1098.  
  1099.     return (params);
  1100. }
  1101.  
  1102.  
  1103. void normalize(vector v)
  1104. {
  1105.     float r;
  1106.  
  1107.     r = sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]);
  1108.  
  1109.     v[X] /= r;
  1110.     v[Y] /= r;
  1111.     v[Z] /= r;
  1112. }
  1113.  
  1114.  
  1115. float dot(vector v1, vector v2)
  1116. {
  1117.     return v1[X]*v2[X]+v1[Y]*v2[Y]+v1[Z]*v2[Z];
  1118. }
  1119.  
  1120.